home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / matrix.lha / Matrix / src / genclass < prev    next >
Encoding:
Text File  |  1993-02-25  |  10.4 KB  |  457 lines

  1. #!/bin/sh
  2.  
  3. #   Copyright (C) 1989 Free Software Foundation, Inc.
  4. #   
  5. #   genclass program enhanced by Wendell C. Baker 
  6. #   (original by Doug Lea (dl@rocky.oswego.edu))
  7.  
  8. #This file is part of GNU libg++.
  9.  
  10. #GNU libg++ is free software; you can redistribute it and/or modify
  11. #it under the terms of the GNU General Public License as published by
  12. #the Free Software Foundation; either version 1, or (at your option)
  13. #any later version.
  14.  
  15. #GNU libg++ is distributed in the hope that it will be useful,
  16. #but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18. #GNU General Public License for more details.
  19.  
  20. #You should have received a copy of the GNU General Public License
  21. #along with GNU libg++; see the file COPYING.  If not, write to
  22. #the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  23.  
  24.  
  25. #
  26. # genclass -list [proto ...]
  27. # genclass -catalog [proto ...]
  28. # genclass type1 {ref|val} proto [out_prefix]
  29. # genclass -2 type1 {ref|val} type2 {ref, val} proto [out_prefix]
  30. #
  31. # Generate classes from prototypes
  32. #
  33. name=genclass ;
  34. usage="
  35.     $name -list [proto ...]
  36.     $name -catalog [proto ...]
  37.     $name type1 {ref|val} proto [out_prefix]
  38.     $name -2 type1 {ref|val} type2 {ref|val} proto [out_prefix]" ;
  39.  
  40. case "$1" in
  41. -usage)
  42.     #
  43.     # -usage
  44.     #
  45.     echo "usage: $usage" 1>&2 ;
  46.     exit 0;
  47.     ;;
  48. -version)
  49.     #
  50.     # -version
  51.     #
  52.     # Maybe this version number should be the version number of
  53.     # the libg++ from whence this came - edited in during the
  54.     # installation process...
  55.     version="`expr '$Revision: 1.2 $' : '.*Revision: \(.*\) .*'`" ;
  56.     echo "$name: version $version" ;
  57.     exit 0;
  58.     ;;
  59. -requires)
  60.     #
  61.     # -requires
  62.     #
  63.     # The following line should contain any nonstandard programs
  64.     # which must be in the users's path (i.e. not referenced by a
  65.     # fullpath);it allows one to check a script for dependencies
  66.     # without exhaustively testing its usages.
  67.     # ... in this case genclass depends on nothing else.
  68.     echo ;
  69.     exit 0;
  70.     ;;
  71. esac ;
  72.  
  73. # pull it in from the environment
  74. [ "$TRACE" = "" ] || set -xv 
  75.  
  76. # Search in standard g++ prototype directory and in the current directory
  77. # NOTE: this variable is edited by the install process
  78. PROTODIR=${PROTODIR-/usr/local/lib/g++-include/gen}
  79.  
  80. pwd=`pwd`
  81.  
  82. case "$1" in
  83. -catalog*|-list*)
  84.     #
  85.     # genclass -catalog [proto ...]
  86.     # genclass -list [proto ...]
  87.     #
  88.     option="$1" ;
  89.     shift ;
  90.  
  91.     case $# in
  92.     0)
  93.         #
  94.         # -catalog
  95.         # -list
  96.         #
  97.         select=all ;
  98.         select_pattern=p ;
  99.         ;;
  100.     *)
  101.         #
  102.         # -catalog proto ...
  103.         # -list proto ...
  104.         #
  105.         select="$@" ;
  106.         select_pattern= ;
  107.         for i in $@ ; do
  108.             select_pattern="\
  109. $select_pattern
  110. /.*$i\$/ p
  111. " ;
  112.         done ;
  113.  
  114.         ;;
  115.     esac ;
  116.  
  117.     #
  118.     # select_pattern is now a (possibly-vacuous) newline-
  119.     # separated list of patterns of the form:
  120.     #
  121.     #     /.*Proto1$/ p
  122.     #     /.*Proto2$/ p
  123.     #     /.*Proto3$/ p
  124.     #
  125.     # or select_pattern is simply ``p'' to select everything
  126.  
  127.     # Hmmm... not all systems have a fmt program; should we
  128.     # just go ahead and use ``nroff -Tcrt | cat -s'' here?
  129.     fmt='nroff -Tcrt | cat -s'
  130.     #fmt=fmt ;
  131.  
  132.     case "$option" in
  133.     -catalog*)
  134.         #
  135.         # -catalog [proto ...]
  136.         #
  137.         echo "\
  138. Catalog of ${name} class templates
  139. directories searched:
  140.     $PROTODIR
  141.     $pwd
  142. selecting: $select
  143. classes available:" ;
  144.         ;;
  145.     -list*)
  146.         #
  147.         # -list [proto ...]
  148.         #
  149.         # no need to do anything (the list is coming out next)
  150.         ;;
  151.     esac ;
  152.  
  153.     ls $pwd $PROTODIR | sed -e '
  154. # If it does not end in a .ccP or .hP then
  155. # its not a template and we are not intereseted
  156. /\.ccP$/ !{
  157.    /\.hP$/ !{
  158.      d
  159.    }
  160. }
  161. # Get rid of pathname components
  162. s;.*/;;
  163. # Just take the template names
  164. s/\.ccP$//
  165. s/\.hP$//
  166. ' -e "
  167. # change quoting conventsions and
  168. # select off what we want to see
  169. $select_pattern
  170. # if it did not pass the patterns, kill it
  171. d
  172. " | sort -u | case "$option" in
  173.     -catalog*)
  174.         # The library catalog information preceded the list
  175.         # format the list, and tab in in a bit to make it readable.
  176.         # Re-evaluate $fmt because it might contain a shell command
  177.         eval $fmt | sed -e 's/.*/    &/' ;
  178.         ;;
  179.     -list*)
  180.         # nothing special, just let the sorted list dribble out
  181.         # we must use cat to receive (and reproduce) the incoming list
  182.         cat ;
  183.         ;;
  184.     esac ;
  185.     exit 0;
  186.     ;;
  187. -2)
  188.     #
  189.     # genclass -2 type1 {ref|val} type2 {ref|val} proto [out_prefix]
  190.     #
  191.     N=2 ;
  192.  
  193.     case $# in
  194.     6) # genclass -2 type1 {ref|val} type2 {ref|val} proto
  195.        ;;
  196.     7) # genclass -2 type1 {ref|val} type2 {ref|val} proto out_prefix
  197.        ;;
  198.     *)
  199.     echo "usage: $usage" 1>&2 ;
  200.     exit 1;
  201.     esac ;
  202.     shift ;
  203.     ;;
  204. *)
  205.     #
  206.     # genclass type1 {ref|val} proto [out_prefix]
  207.     #
  208.     N=1 ;
  209.  
  210.     case $# in
  211.     3) # genclass type1 {ref|val} proto
  212.        ;;
  213.     4) # genclass type1 {ref|val} proto out_prefix
  214.        ;;
  215.     *)
  216.     echo "usage: $usage" 1>&2 ;
  217.     exit 1;
  218.     esac ;
  219.     ;;
  220. esac
  221.  
  222. #
  223. # Args are now (the point being the leading ``-2'' is gone)
  224. #
  225. #     type1 {ref|val} proto [out_prefix]
  226. #     type1 {ref|val} type2 {ref|val} proto [out_prefix]
  227. #
  228.  
  229. #
  230. # Quote all of the $1 $2 etc references to guard against
  231. # dynamic syntax errors due to vacuous arguments (i.e. '')
  232. # as sometimes occurs when genclass is used from a Makefile
  233. #
  234.  
  235. T1="$1";
  236. T1NAME="$T1." ;
  237. T1SEDNAME="$T1" ;
  238.  
  239. case "$2" in
  240. ref)
  241.      T1ACC="\&" ;
  242.      ;;
  243. val)
  244.      T1ACC=" " ;
  245.      ;;
  246. *)
  247.     echo "${name}: Must specify type1 access as ref or val" 1>&2 ;
  248.     echo "usage: $usage" 1>&2 ;
  249.     exit 1;
  250.     ;;
  251. esac
  252.  
  253. # N is either 1 or 2
  254.  
  255. case $N in
  256. 1)
  257.     #
  258.     # type1 {ref|val} proto [out_prefix]
  259.     #
  260.     class="$3" ;
  261.  
  262.     T2="" ;
  263.     T2ACC="" ;
  264.     ;;
  265. 2)
  266.     #
  267.     # type1 {ref|val} type2 {ref|val} proto [out_prefix]
  268.     #
  269.     class="$5" ;
  270.  
  271.     T2="$3";
  272.     T2NAME="$T2." ;
  273.     T2SEDNAME="$T2" ;
  274.  
  275.     case "$4" in
  276.     ref)
  277.         T2ACC="\&" ;
  278.         ;;
  279.     val)
  280.         T2ACC=" " ;
  281.         ;;
  282.      *)
  283.         echo "${name}: Must specify type2 access: ref or val" 1>&2 ;
  284.     echo "usage: $usage" 1>&2 ;
  285.     exit 1;;
  286.     esac;
  287.     ;;
  288. esac
  289.  
  290. defaultprefix="$T1NAME$T2NAME" ;
  291.  
  292. case $# in
  293. 3)  # type1 {ref|val} proto
  294.     replaceprefix="N" ;
  295.     prefix="$defaultprefix" ;
  296.     ;;
  297. 5)  # type1 {ref|val} type2 {ref|val} proto
  298.     replaceprefix="N" ;
  299.     prefix="$defaultprefix" ;
  300.     ;;
  301. 4)  # type1 {ref|val} proto out_prefix
  302.     prefix="$4" ;
  303.     replaceprefix="Y" ;
  304.     ;;
  305. 6)  # type1 {ref|val} type2 {ref|val} proto out_prefix
  306.     prefix="$6" ;
  307.     replaceprefix="Y" ;
  308.     ;;
  309. *)
  310.     echo "${name}: too many arguments" 1>&2 ;
  311.     echo "usage: $usage" 1>&2 ;  
  312.     exit 1;
  313.     ;;
  314. esac ;
  315.  
  316. src_h=$class.hP
  317. src_cc=$class.ccP
  318. out_h=$prefix$class.h;
  319. out_cc=$prefix$class.C ;
  320.  
  321. #
  322. # Note #1: The .h and .cc parts are done separately
  323. #     in case only a .h exists for the prototype
  324. #
  325. # Note #2: Bind the .h and .cc parts to the fullpath
  326. #     directories at the same time to ensure consistency.
  327. #
  328.  
  329. if [ -f $pwd/$src_h ] ; then
  330.     fullsrc_h=$pwd/$src_h ;
  331.     fullsrc_cc=$pwd/$src_cc ;
  332. elif [ -f $PROTODIR/$src_h ] ; then
  333.     fullsrc_h=$PROTODIR/$src_h ;
  334.     fullsrc_cc=$PROTODIR/$src_cc ;
  335. else
  336.     echo "${name}: there is no prototype for class $class - file $src_h" 1>&2 ;
  337.     $0 -list ;
  338.     exit 1;
  339. fi
  340.  
  341. CASES="$N$replaceprefix" ;
  342. # CASES is one of { 2Y 2N 1Y 1N }
  343.  
  344. #
  345. # WATCHOUT - we have no way of checking whether or not
  346. # the proper case type is being used with the prototype.
  347. #
  348. # For example, we have no way of ensuring that any of
  349. # Map variants are specified with the -2 argument set
  350. # Further, we have no way of ensuring that -2 is not
  351. # used with the prototypes which require only one.
  352. #
  353. # The second problem is not serious because it still
  354. # results in correctly-generated C++ code; the first
  355. # problem is serious because it results in C++ code that
  356. # still has ``<C>'' and ``<C&>'' syntax inside it.  Such
  357. # code of course will not compile.
  358. #
  359. # SO THE BEST WE CAN DO - is check for the presence of
  360. # <C> and <C&> AFTER the thing has been generated.
  361. #
  362. # Path for System 5 m4 preprocessor.
  363. SYS5=/usr/5bin
  364.  
  365. case $CASES in
  366. 2Y) # Two output substitutions, change the prefix
  367.     $SYS5/m4 -B8192 -Dbasetype=$T1 < $fullsrc_h | sed > $out_h -e "
  368. s/<T>/$T1/g
  369. s/<T&>/$T1$T1ACC/g
  370. s/<C>/$T2/g
  371. s/<C&>/$T2$T2ACC/g
  372. s/$T1SEDNAME\.$T2SEDNAME\./$prefix/g
  373. s/$T1SEDNAME\./$prefix/g
  374. s/$T2SEDNAME\./$prefix/g
  375. " ;
  376.     ;;
  377. 2N) # Two output substitutions, use the default prefix
  378.     $SYS5/m4 -B8192 -Dbasetype=$T1 < $fullsrc_h | sed > $out_h -e "
  379. s/<T>/$T1/g
  380. s/<T&>/$T1$T1ACC/g
  381. s/<C>/$T2/g
  382. s/<C&>/$T2$T2ACC/g
  383. " ;
  384.     ;;
  385. 1Y) # One output substitution, change the prefix
  386.     $SYS5/m4 -B8192 -Dbasetype=$T1 < $fullsrc_h | sed > $out_h -e "
  387. s/<T>/$T1/g
  388. s/<T&>/$T1$T1ACC/g
  389. s/$T1SEDNAME\./$prefix/g
  390. " ;
  391.     ;;
  392. 1N) # One output substitution, use the default prefix
  393.     $SYS5/m4 -B8192 -Dbasetype=$T1 < $fullsrc_h | sed > $out_h -e "
  394. s/<T>/$T1/g
  395. s/<T&>/$T1$T1ACC/g
  396. " ;
  397.     ;;
  398. esac
  399.  
  400. if egrep '<C&?>' $out_h > /dev/null ; then
  401.     echo "${name}: the $class class requires the -2 syntax for the 2nd type" 1>&2 ;
  402.     echo "usage: $usage" 1>&2 ;
  403.     # the user does not get to see the mistakes (he might try to compile it)
  404.     rm $out_h ;
  405.     exit 1;
  406. fi ;
  407.  
  408. if [ ! -f $fullsrc_cc ] ; then
  409.     echo "${name}: warning, class has a .h but no .cc file" 1>&2 ;
  410.     exit 0;
  411. fi
  412.  
  413. case $CASES in
  414. 2Y) # Two output substitutions, change the prefix
  415.     $SYS5/m4 -B8192 -Dbasetype=$T1 < $fullsrc_cc | sed > $out_cc -e "
  416. s/<T>/$T1/g
  417. s/<T&>/$T1$T1ACC/g
  418. s/<C>/$T2/g
  419. s/<C&>/$T2$T2ACC/g
  420. s/$T1SEDNAME\.$T2SEDNAME\./$prefix/g
  421. s/$T1SEDNAME\./$prefix/g
  422. s/$T2SEDNAME\./$prefix/g
  423. "
  424.     ;;
  425. 2N) # Two output substitutions, use the default prefix
  426.     $SYS5/m4 -B8192 -Dbasetype=$T1 < $fullsrc_cc | sed > $out_cc -e "
  427. s/<T>/$T1/g
  428. s/<T&>/$T1$T1ACC/g
  429. s/<C>/$T2/g
  430. s/<C&>/$T2$T2ACC/g
  431. "
  432.     ;;
  433. 1Y) # One output substitution, change the prefix
  434.     $SYS5/m4 -B8192 -Dbasetype=$T1 < $fullsrc_cc | sed > $out_cc -e "
  435. s/<T>/$T1/g
  436. s/<T&>/$T1$T1ACC/g
  437. s/$T1SEDNAME\./$prefix/g
  438. "
  439.     ;;
  440. 1N) # One output substitution, use the default prefix
  441.     $SYS5/m4 -B8192 -Dbasetype=$T1 < $fullsrc_cc | sed > $out_cc -e "
  442. s/<T>/$T1/g
  443. s/<T&>/$T1$T1ACC/g
  444. "
  445.     ;;
  446. esac
  447.  
  448. if egrep '<C&?>' $out_h $out_cc > /dev/null ; then
  449.     echo "${name}: the $class class requires the -2 syntax for the 2nd type" 1>&2 ;
  450.     echo "usage: $usage" 1>&2 ;
  451.     # the user does not get to see the mistakes (he might try to compile it)
  452.     rm $out_h $out_cc ;
  453.     exit 1;
  454. fi ;
  455.  
  456. exit 0;
  457.